import { closeDB, getDB } from "@/utils/db";
import { err } from "@/utils/resp";
import { toClash, toV2ray } from "@/utils/sub";
import { NextRequest } from "next/server";

export async function GET(
  { nextUrl: { searchParams: sp } }: NextRequest,
  { params: { id } }: { params: { id: string } }
) {
  try {
    const type = sp.get("t") || "v2ray"; // 类型：v2ray、clash
    const cfip = sp.get("cf") || ""; // 优选
    const skip = sp.get("s") || ""; // 跳过
    let includeOrgin = sp.get("o") || ""; // 是否包含原始节点

    const db = await getDB();

    const count: Count = (await db.get(
      "SELECT COUNT(*) AS num FROM subs WHERE id=?",
      id
    )) || { num: 0 };
    if (!count.num) {
      throw new Error("你在想屁吃");
    }

    const cf: Cfip | undefined = await db.get(
      "SELECT ip FROM cfips WHERE code=?",
      cfip
    );
    if (!cf) {
      includeOrgin = "1";
    }

    const where: string[] = [];
    const params: string[] = [];

    if (skip) {
      const skipWhere: string[] = [];
      const skipParams: string[] = [];
      skip
        .split(",")
        .filter((s) => s.trim().length > 0)
        .forEach((s) => {
          skipWhere.push("name LIKE '%' || ? || '%'");
          skipParams.push(s);
        });
      where.push(
        ` AND id NOT IN(SELECT id FROM nodes WHERE ${skipWhere.join(" OR ")})`
      );
      params.push(...skipParams);
    }
    const sql = `SELECT id, "type", name, host, port, password, "path" FROM nodes WHERE 1=1 ${where.join(
      " "
    )} ORDER BY id ASC`;
    const nodes: SubmeNode[] = await db.all(sql, ...params);
    await closeDB();

    const using_cfip = cf?.ip || "";
    if (type === "v2ray") {
      const subStr = toV2ray(nodes, using_cfip, includeOrgin === "1");
      return new Response(subStr, {
        headers: { "content-type": "text/plain" },
      });
    }
    if (type == "clash") {
      const subStr = toClash(nodes, using_cfip, includeOrgin === "1");
      return new Response(subStr, {
        headers: { "content-type": "application/yaml" },
      });
    }
    throw new Error("你在想屁吃");
  } catch (e) {
    return err(e as Error);
  }
}
